package com.hu.biz.serviceImpl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.hu.biz.service.MyService;
import com.hu.biz.util.Excel2SqlUtil;
import com.hu.common.constants.PushMouldConstant;
import com.hu.common.domain.dto.PreEmpBaseInfoDTO;
import com.hu.common.domain.vo.QuanXianVO;
import com.hu.common.enums.PreEmpResultEnum;
import com.hu.common.enums.PreEmpTypeEnum;
import com.hu.common.enums.RoleEnum;
import com.hu.common.util.adm.Assert;
import com.hu.common.util.help.DataOperateHelper;
import com.hu.dao.entity.SceneEntity;
import com.hu.dao.mapper.MyServiceMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.*;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author 00355760
 * @功能：
 * @版本： V1
 * @版权： 信息技术有限公司（http://www.mychery.com/）
 * @作者： 磐石战队开发组  00355760
 * @日期： 2025/1/2 15:12
 */
@Slf4j
@RequiredArgsConstructor
public class MyServiceImpl extends ServiceImpl<MyServiceMapper, SceneEntity> implements MyService {

    private final MyServiceMapper myServiceMapper;
    private final TimeUnit timeUnit = TimeUnit.HOURS;
    private final Integer BATCH_SIZE = 500;

    @Override
    public void getAdmin() {
        QuanXianVO item = new QuanXianVO();
        List<String> staffCodeList = Optional.ofNullable(item.getAdminCodeListStr()).map(str -> Arrays.asList(str.split(","))).orElseGet(ArrayList::new);
        item.setIsAdmin(DataOperateHelper.isAdmin(ListUtil.of(RoleEnum.ADMIN_SYSTEM, RoleEnum.ADMIN_MODEL_CRAFTSMAN), staffCodeList));
        item.setCanTop(DataOperateHelper.canTop(ListUtil.of(RoleEnum.ADMIN_TOP)));
        item.setWithDrawAdmin(DataOperateHelper.withDrawAdmin(ListUtil.of(RoleEnum.ADMIN_WITHDRAW)));
    }

    @Override
    public String createSalt() {
        StringBuilder salt = new StringBuilder();
        // 生成盐值
        int saltLength = 6;
        for (int i = 0; i < saltLength; i += 1) {
            salt.append((char) (RandomUtils.nextInt() + 97));
        }
        return salt.toString().trim();
    }

    @Override
    public void batch(List<SceneEntity> list) {
        if (Assert.notEmptyCollection(list)) {
            int REPARSE_MAX_COUNT = 100;
            List<List<SceneEntity>> partition = Lists.partition(list, REPARSE_MAX_COUNT);
            partition.forEach(this::saveBatch);
        }
    }

    @Override
    public Long batchTiming(Integer batchSize) {
        batchSize = ObjectUtil.defaultIfNull(batchSize, BATCH_SIZE);
        // 获取分组总待办([待审批02、直接上级评价30、对话50]，且过滤有待办但没有目标or计划的)
        List<String> sysTodoList = new ArrayList<>();
        if (CollectionUtil.isEmpty(sysTodoList)) {
            return 0L;
        }
        Map<String, Long> countMap = sysTodoList.stream().collect(Collectors.groupingBy(String::toString, Collectors.counting()));
        int total = countMap.size();
        // 获取 map 的条目集合
        Set<Map.Entry<String, Long>> entries = countMap.entrySet();
        // 计算需要分割的批次数量
        int numberOfBatches = (int) Math.ceil((double) entries.size() / batchSize);
        log.info("定时催办批次数量：{}，每批{}条", numberOfBatches, batchSize);
        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(numberOfBatches);
        // 遍历条目列表，按批次分割数据
        for (int i = 0; i < numberOfBatches; i++) {
            int start = i * batchSize;
            int end = Math.min(start + batchSize, entries.size());
            // 获取当前批次的条目列表
            List<Map.Entry<String, Long>> batchData = new ArrayList<>(entries).subList(start, end);
            // 处理当前批次的数据
            processBatch(batchData, i, scheduledExecutorService);
        }
        // 为了防止主线程立即退出，可以添加一个等待机制
        try {
            scheduledExecutorService.shutdown();
        } catch (Exception e) {
            log.error("定时催办线程等待异常：", e);
        }
        return Convert.toLong(total);
    }

    @Override
    public LinkedHashMap<String, String> batchException(PreEmpBaseInfoDTO preEmpBaseInfoDTO) {
        LinkedHashMap<String, String> failMsg = new LinkedHashMap<>();
        // 身高 工人必填
        if (ObjectUtil.isEmpty(preEmpBaseInfoDTO.getBodyHeight()) && PreEmpTypeEnum.WORKER.equals(preEmpBaseInfoDTO.getPreEmpType())) {
            failMsg.put("bodyHeight", PreEmpResultEnum.P3001.message());
        }
        // 体重 工人必填
        if (ObjectUtil.isEmpty(preEmpBaseInfoDTO.getBodyWeight()) && PreEmpTypeEnum.WORKER.equals(preEmpBaseInfoDTO.getPreEmpType())) {
            failMsg.put("bodyWeight", PreEmpResultEnum.P3002.message());
        }
        // 国家/地区--名称 社招、校招、高招必填
        if (ObjectUtil.isEmpty(preEmpBaseInfoDTO.getCountryName())
                && (PreEmpTypeEnum.SOCIAL.equals(preEmpBaseInfoDTO.getPreEmpType()) || PreEmpTypeEnum.SCHOOL.equals(preEmpBaseInfoDTO.getPreEmpType())
                || PreEmpTypeEnum.EXPERT.equals(preEmpBaseInfoDTO.getPreEmpType()))) {
            failMsg.put("countryName", PreEmpResultEnum.P3002.message());
        }
        // 第一次参加工作时间 工人、校招、高招必填
        if (ObjectUtil.isEmpty(preEmpBaseInfoDTO.getJoinWorkDate())
                && (PreEmpTypeEnum.WORKER.equals(preEmpBaseInfoDTO.getPreEmpType()) || PreEmpTypeEnum.SCHOOL.equals(preEmpBaseInfoDTO.getPreEmpType())
                || PreEmpTypeEnum.EXPERT.equals(preEmpBaseInfoDTO.getPreEmpType()))) {
            failMsg.put("joinWorkDate", PreEmpResultEnum.P3004.message());
        }
        // 目前工作单位 工人必填
        if (ObjectUtil.isEmpty(preEmpBaseInfoDTO.getCurrentEmployerName()) && PreEmpTypeEnum.WORKER.equals(preEmpBaseInfoDTO.getPreEmpType())) {
            failMsg.put("currentEmployerName", PreEmpResultEnum.P3008.message());
        }
        // 缴纳保险类型 工人必填
        if (ObjectUtil.isEmpty(preEmpBaseInfoDTO.getSiType()) && PreEmpTypeEnum.WORKER.equals(preEmpBaseInfoDTO.getPreEmpType())) {
            failMsg.put("siType", PreEmpResultEnum.P3013.message());
        }
        // 应聘部门--名称 工人必填
        if (ObjectUtil.isEmpty(preEmpBaseInfoDTO.getAppliedDeptShortName()) && PreEmpTypeEnum.WORKER.equals(preEmpBaseInfoDTO.getPreEmpType())) {
            failMsg.put("appliedDeptShortName", PreEmpResultEnum.P3019.message());
        }

        return failMsg;
    }

    private void processBatch(List<Map.Entry<String, Long>> batchData, int batch, ScheduledExecutorService executor) {
        Runnable task = () -> {
            log.info("定时催办批次【{}】开始处理【{}】条数据", batch, batchData.size());
            batchData.forEach(entry -> {
                String dealPersonCode = entry.getKey();
                Long todoCount = entry.getValue();
                if (ObjectUtil.isNotNull(todoCount) && !todoCount.equals(0L)) {
                    String message = PushMouldConstant.DAILY_TODO_REMIND.replace("{count}", String.valueOf(todoCount));
                    // 发送飞书消息
                    System.out.println(message);
                }
            });
        };
        executor.schedule(task, batch, timeUnit);
    }


    @Override
    public String parseExcel(MultipartFile file) throws IOException {
        Excel2SqlUtil.excel2UserRoleSql(file);
        return "success";
    }

}
